home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_100 / 129_01 / 210modem.c < prev    next >
Text File  |  1985-03-09  |  25KB  |  819 lines

  1. /************************************************************************/
  2. /*                modem.c                 */
  3. /*                                    */
  4. /*        modem code for Citadel bulletin board system        */
  5. /*    NB: this code is rather machine-dependent:  it will typically    */
  6. /*    need some twiddling for each new installation.            */
  7. /*                  82Nov05 CrT                */
  8. /************************************************************************/
  9.  
  10. /************************************************************************/
  11. /*                history                 */
  12. /*                                    */
  13. /* 85Jan12 HAW    SECONDSFACTOR == secondsfactor now, for portability.    */
  14. /* 84Dec28 HAW    Ensure execution of HANGUP when carrier is lost.    */
  15. /* 84Dec16 JLS&HAW Start installation of new WC protocol downloader.    */
  16. /* 84Aug22 HAW    Compilation directive for 8085 chips inserted.        */
  17. /* 84Jul08 JLS & HAW ReadFile() fixed for the 255 rollover.        */
  18. /* 84Jul03 JLS & HAW All references to putCh changed to putChar.    */
  19. /* 84Jun23 HAW & JLS Local unused variables zapped.            */
  20. /* 84Mar07 HAW    Upgrade to BDS 1.50a begun.                */
  21. /* 83Mar01 CrT    FastIn() ignores LFs etc -- CRLF folks won't be trapped.*/
  22. /* 83Feb25 CrT    Possible fix for backspace-in-message-entry problem.    */
  23. /* 83Feb18 CrT    fastIn() upload mode cutting in on people.  Fixed.    */
  24. /* 82Dec16 dvm    modemInit revised for FDC-1, with kludge for use with    */
  25. /*        Big Board development system                */
  26. /* 82Dec06 CrT    2.00 release.                        */
  27. /* 82Nov15 CrT    readfile() & sendfile() borrowed from TelEdit.c     */
  28. /* 82Nov05 CrT    Individual history file established            */
  29. /************************************************************************/
  30.  
  31. #include <210ctdl.h>
  32.  
  33. /************************************************************************/
  34. /*                Contents                */
  35. /*                                    */
  36. /*    BBSCharReady()        returns true if user input is ready    */
  37. /*    doWC()            startup routine for the WC downloader.    */
  38. /*  #    fastIn()        kludge code compiling other stuff inline*/
  39. /*    getCh()         bottom-level console-input filter    */
  40. /*  #    getMod()        bottom-level modem-input   filter    */
  41. /*    iChar()         top-level user-input function        */
  42. /*    interact()        chat mode                */
  43. /*    interpret()        interprets a configuration routine    */
  44. /*    KBReady()        returns TRUE if a console char is ready */
  45. /*    mOReady()        returns true if modem can accept a char */
  46. /*    modIn()         returns a user char            */
  47. /*    modemInit()        top-level initialize-all-modem-stuff    */
  48. /*    oChar()         top-level user-output function        */
  49. /*  #    outMod()        bottom-level modem output        */
  50. /*    pause()         pauses for N/100 seconds        */
  51. /*  #    putChar()                            */
  52. /*    readFile()        accept a file using WC protocol     */
  53. /*    receive()        read modem char or time out        */
  54. /*    ringSysop()        signal chat-mode request        */
  55. /*    sendWCChar()        Helps chuck output via WC protocol.    */
  56. /*                                    */
  57. /*    # == routines you should certainly check when porting system    */
  58. /************************************************************************/
  59.  
  60. /************************************************************************/
  61. /*        The principal dependencies:                */
  62. /*                                    */
  63. /*  iChar   modIn                    outMod        */
  64. /*        modIn   getMod  getCh   mIReady kBReady outMod  carrDetect    */
  65. /*            getMod                        */
  66. /*                getCh                    */
  67. /*                    mIReady                */
  68. /*                        kBReady            */
  69. /*                                carrDetect    */
  70. /*                                    */
  71. /*  oChar                        outMod        */
  72. /*                            outMod  mOReady    */
  73. /************************************************************************/
  74.  
  75.  
  76. /************************************************************************/
  77. /*    BBSCharReady() returns TRUE if char is available from user    */
  78. /*    NB: user may be on modem, or may be sysop in CONSOLE mode    */
  79. /************************************************************************/
  80. char BBSCharReady()
  81. {
  82.     char KBReady();
  83.  
  84.     return ((haveCarrier       &&   interpret(pMIReady))
  85.      || (whichIO==CONSOLE  &&   KBReady()           )
  86.     );
  87. }
  88.  
  89. /************************************************************************/
  90. /*    doWC() is the initialization routine for WC downloading.  If    */
  91. /*    called with mode == STARTUP, it sets up globals and gets ready    */
  92. /*    for the initial NAK.  If mode == anything else, then it cleans    */
  93. /*    up after the downloader.                    */
  94. /************************************************************************/
  95. doWC(mode)
  96. char mode;        /* See above */
  97. {
  98.     int i, m;
  99.  
  100.     if (mode == STARTUP) {    /* Setup globals for the coming fun.    */
  101.     WCError  = FALSE;
  102.     WCSecNum = 1;
  103.     i     = 0;
  104.     WCChar     = 0;
  105.     while (1) {        /* Get that darn initial NAK        */
  106.         m = receive(MINUTE);
  107.         if (m == CAN || m == ERROR) /* Didn't get initial        */
  108.         return FALSE;        /* NAK, so time out ..        */
  109.         if (m == NAK)        /* There it is!         */
  110.         return TRUE;
  111.         if (++i == ERRORMAX)    /* 10 chars, no NAKs?        */
  112.         return FALSE;        /* Then ferget it.        */
  113.     }
  114.     }
  115.     else {    /* Cleanup after downloader                */
  116.     if (WCError) return;
  117.     for (; WCChar != 0 && sendWCChar(' ');)
  118.         ;                    /* Do final sector    */
  119.     if (WCError) return;
  120.     for (i = 0; i < ERRORMAX; i++) {
  121.         outMod(EOT);
  122.         if (receive(MINUTE) == ACK || !haveCarrier) break;
  123.     }
  124.     }
  125. }
  126.  
  127. /************************************************************************/
  128. /*    fastIn() is  a special kludge to read in text from the modem    */
  129. /*    as quickly as possible, to allow message upload without     */
  130. /*    handshaking.  Hence we hand-compile some other routines inline    */
  131. /*    Called only from getText(), when whichIO==MODEM.        */
  132. /*    Externals:    see below                     */
  133. /*                                    */
  134. /*    This code is probably overkill for 300 baud, but it may handle    */
  135. /*    1200 baud as well.                        */
  136. /*                                    */
  137. /*    code being speed-optimized would normally be:            */
  138. /*                                    */
  139. /*    while (                             */
  140. /*        !(    (c=iChar()) == NEWLINE     &&   buf[i-1] == NEWLINE )    */
  141. /*        &&    i < lim                         */
  142. /*        &&    (haveCarrier || whichIO == CONSOLE)            */
  143. /*    ) {                                */
  144. /*        if (c != BACKSPACE)  buf[i++] = c;                */
  145. /*        else {                            */
  146. /*        /  handle deletes:     /                */
  147. /*        oChar(' ');                        */
  148. /*        oChar(BACKSPACE);                    */
  149. /*        if (i>0  &&  buf[i-1] != NEWLINE)  i--;         */
  150. /*        else                   oChar(BELL);     */
  151. /*        }                                */
  152. /*    }                                */
  153. /************************************************************************/
  154. #define cursor        fpc1        /* external char *        */
  155. #define BUFEND        fpc2        /* external char *        */
  156. #define tryCount    fi1        /* external int         */
  157. #define isFast        fi2        /* external int         */
  158. #define ch        fc1        /* external char        */
  159. #define lastWasNL    fc2        /* external char        */
  160. #define slow        fc3        /* external char        */
  161. fastIn(continuing)
  162. char continuing;    /* TRUE if we are continuing a message    */
  163. {
  164.     char cache, notFinished;
  165.     int  tryStart, shortTime;
  166.  
  167.     isFast    = 0;
  168.  
  169.     tryStart    = 500*megaHz;
  170.     shortTime    = 480*megaHz;
  171.     cursor    = &msgBuf.mbtext[0      ];
  172.     BUFEND    = &msgBuf.mbtext[MAXTEXT-1];
  173.  
  174.     if (continuing)   while (*cursor) ++cursor; /* find where we were    */
  175.  
  176.     notFinished = TRUE;
  177.     lastWasNL    = FALSE;
  178.  
  179.     /* put newline at start of buffer to simplify BACKSPACE check:    */
  180.     cache          = msgBuf.mbtext[-1];
  181.     msgBuf.mbtext[-1]      = NEWLINE;
  182.  
  183.     while (notFinished     &&   cursor < BUFEND) {
  184.     tryCount = tryStart;    /* try to be waiting for each char    */
  185.     while (--tryCount  &&  !interpret(pMIReady));
  186.  
  187.     if (tryCount>shortTime) isFast++;
  188.     else            isFast--;
  189.  
  190.     if (!tryCount) {
  191.         /* no modem char -- take break to check other stuff */
  192.         if (KBReady()) {
  193.         if (getCh() == SPECIAL) {
  194.             mPrintf("\n system is now in CONSOLE mode.\n ");
  195.             whichIO    = CONSOLE;
  196.             notFinished = FALSE;
  197.             setUp(FALSE);
  198.         }
  199.         }
  200.         if (!interpret(pCarrDetect)) {
  201.         modIn();    /* let modIn() announce it etc    */
  202.         notFinished    = FALSE;
  203.         }
  204.     } else {
  205.         /* time to read modem char: */
  206.         switch (ch =  filter[ inp(mData) & 0x7F ]) {
  207.         case NEWLINE:
  208.         if (lastWasNL)    {
  209.             notFinished = FALSE;
  210.         } else {
  211.             lastWasNL    = TRUE;
  212.  
  213.             *cursor++    = ch;
  214.  
  215.             if (isFast>0  ||  !termLF)     ch = '\r';
  216.             else {
  217.             oChar('\r');
  218.             while (!interpret(pMOReady));    /* for outp()    */
  219.             }
  220.         }
  221.         isFast    = 0;    /* figure speed of each line independently */
  222.         break;
  223.         case BACKSPACE:
  224.         /* people don't upload backspaces --